home *** CD-ROM | disk | FTP | other *** search
/ Turnbull China Bikeride / Turnbull China Bikeride - Disc 1.iso / ARGONET / PD / FILER / TARSRC.SPK / c / extract < prev    next >
Text File  |  1994-08-05  |  5KB  |  200 lines

  1. /* Extract files from archive */
  2.  
  3. #include "tar.h"
  4. #include "args.h"
  5. #include "dir.h"
  6. #include "tapeio.h"
  7. #include "table.h"
  8. #include "extract.h"
  9.  
  10.  
  11. static int ConfirmObject(char c, char *name, CatInfo *InfoBlk) {
  12.   if (!ConfirmActions || QuietExecution) {
  13.     return (1);
  14.   }
  15.   printf("%c ", c);
  16.   if (Verbose)
  17.     VerboseContents(InfoBlk);
  18.   printf("%s: ", name);
  19.   return (Decision('n') == 'y') ? 1 : 0;
  20. } /* ConfirmObject */
  21.  
  22.  
  23. static int CheckPath(char *name, int truedir) {
  24.   char *cp;
  25.  
  26.   if (*(cp = name + strlen(name) - 1) != FS_DIRSEP && truedir &&
  27.       Block.Header.linkflag != LF_DIR)
  28.     return(0);
  29.  
  30.   *cp = '\0';
  31.   if (MakeDir(name) >= 0) {
  32.     if (!truedir) {
  33.       *cp = FS_DIRSEP;
  34.     }
  35.     return (cp[1] == '\0');
  36.   }
  37.  
  38.   *cp = FS_DIRSEP;
  39.   for (cp = name; *cp; cp++) {
  40.     if (*cp != FS_DIRSEP) {
  41.       continue;
  42.     }
  43.     *cp = '\0';
  44.     if (MakeDir(name) < 0) {
  45.       perror(name);
  46.       *cp = FS_DIRSEP;
  47.       return (0);
  48.     }
  49.     *cp = FS_DIRSEP;
  50.   }
  51.   if (truedir && cp[-1] == FS_DIRSEP) {
  52.     cp[-1] = '\0';
  53.     return 1;
  54.   }
  55.   return 0;
  56. } /* CheckPath */
  57.  
  58.  
  59. static void GetObject(CatInfo *InfoBlk) {
  60.   char *leaf,*browse,*filename;
  61.   char save;
  62.   FILE *ofile;
  63.   int ExtentNo;
  64.   long blocks, bytes;
  65.   char buf[RECORDSIZE];
  66.  
  67.   if (!isArchie || Block.Header.archieflag != ARC_FLAG)
  68.     name_to_fs(Block.Header.name);
  69.   if (!ConfirmObject('x', Block.Header.name, InfoBlk)) {
  70.     passtape(InfoBlk->Length);
  71.     return;
  72.   }
  73.   if (CheckPath(Block.Header.name,1)) {
  74.     goto set_attr;
  75.   }
  76.   leaf = Block.Header.name;
  77.   for (browse = leaf; *browse; browse++) {
  78.     if (*browse == FS_DIRSEP) {
  79.       leaf = browse;
  80.     }
  81.   }
  82.   if (*leaf == FS_DIRSEP) {
  83.     leaf++;
  84.     save = *leaf;
  85.     *leaf = 0;
  86.     CheckPath(Block.Header.name,0);
  87.     *leaf = save;
  88.   }
  89.   if (Block.Header.linkflag == LF_EXTENT ||
  90.       Block.Header.linkflag == LF_LASTEXTENT) {
  91.     sscanf(Block.Header.ExtentNo,"%o",&ExtentNo);
  92.   } else {
  93.     ExtentNo = 0;
  94.   }
  95.   if (Block.Header.compressed == CF_COMPRESSED) {
  96.     ChkScrapName();
  97.     filename = ScrapNameZ;
  98.     if (ExtentNo == 1) {
  99.       compress_cleanup();
  100.     }
  101.   } else {
  102.     filename = Block.Header.name;
  103.   }
  104.   if ((ofile = fopen(filename, ExtentNo > 1 ? "ab" : "wb")) == NULL) {
  105.     fprintf(stderr, "tar: %s - cannot %s\n",filename,
  106.             ExtentNo > 1 ? "open" : "create");
  107.     passtape(InfoBlk->Length);
  108.     return;
  109.   }
  110.   blocks = ((bytes = InfoBlk->Length) + RECORDSIZE-1)/RECORDSIZE;
  111.   if (Verbose) {
  112.     fprintf(stderr, "x %s, %ld bytes, ", Block.Header.name, bytes);
  113.     PrintBlocks(stderr, blocks);
  114.     if (Block.Header.compressed == CF_COMPRESSED)
  115.       fprintf(stderr," (%2d%% compressed)",compression);
  116.     if (ExtentNo > 0)
  117.       fprintf(stderr," (extent #%d)",ExtentNo);
  118.     fputc('\n',stderr);
  119.   }
  120.   for (; blocks-- > 0; bytes -= RECORDSIZE) {
  121.     readtape(buf);
  122.     if (bytes > RECORDSIZE) {
  123.       if (fwrite(buf, RECORDSIZE, 1, ofile) < 1) {
  124.         fprintf(stderr,"tar: %s: HELP - extract write error\n",Block.Header.name);
  125.         Terminate(5);
  126.       }
  127.       continue;
  128.     }
  129.     if (fwrite(buf, 1, (int)bytes, ofile) < bytes) {
  130.       fprintf(stderr,"tar: %s: HELP - extract write error\n",Block.Header.name);
  131.       Terminate(6);
  132.     }
  133.   }
  134.   fclose(ofile);
  135.   if (Block.Header.compressed == CF_COMPRESSED &&
  136.       Block.Header.linkflag != LF_EXTENT) {
  137.     if (!ExecuteCommand(DecompressTemplate,ScrapNameZ,Block.Header.name,1))
  138.       return;
  139.     compress_cleanup();
  140.   }
  141. set_attr:
  142.   if (Block.Header.linkflag != LF_EXTENT) {
  143.     SetAttributes(
  144.       DoNotExtractFileDates ?
  145.         4 /* write file attributes */ :
  146.         1 /* write load address, execution address, attributes */,
  147.       Block.Header.name, (int)InfoBlk->Attr,
  148.       (int)InfoBlk->LoadAddress, (int)InfoBlk->ExecAddress);
  149.     if (DoNotExtractFileDates) {
  150.       SetFileType(Block.Header.name, (int)((InfoBlk->LoadAddress >> 8) & 0xFFF));
  151.     }
  152.   }
  153. } /* GetObject */
  154.  
  155.  
  156. void ExtractFiles(void) {
  157.   CatInfo InfoBlk;
  158.   char startdir[256];
  159.   
  160. #if WITH_PWD
  161.   GetCurrentDir(startdir);
  162. #else
  163.   startdir[0] = 0;
  164. #endif
  165.   for (;;) {
  166.     getdir(&InfoBlk);
  167.     if (endtape())
  168.       break;
  169.     switch (Block.Header.linkflag) {
  170.       case LF_LASTEXTENT:
  171.       case LF_EXTENT: {
  172.         int ExtentNo;
  173.         
  174.         sscanf(Block.Header.ExtentNo,"%o",&ExtentNo);
  175.         if (!MultipleVolumes && ExtentNo != 1) {
  176.           fprintf(stderr,"tar: extent #%d of split file %s ignored\n",
  177.             ExtentNo, Block.Header.name);
  178.           passtape(InfoBlk.Length);
  179.           break;
  180.         }
  181.         MultipleVolumes = 1;
  182.         }
  183.       case LF_NORMAL:
  184.       case LF_OLDNORMAL:
  185.       case LF_DIR:
  186.         if (!MatchesNextArg(startdir)) {
  187.           if (VeryVerbose) {
  188.             fprintf(stderr, "- %s\n", Block.Header.name);
  189.           }
  190.           passtape(InfoBlk.Length);
  191.         } else {
  192.           GetObject(&InfoBlk);
  193.         }
  194.         break;
  195.       default:
  196.         break;
  197.     }
  198.   }
  199. } /* ExtractFiles */
  200.